import common.globaldefines
from . import core, const
import application
from adbutils import adb
import cv2
import subprocess
import re

class ScrcpyManager(common.globaldefines.ThreadBase):
    
    _name = "Scrcpy"

    def __init__(self, serial = None):
        super().__init__()
        self._client: core.Client = None
        self._serial = serial
        self._makescreenshot = True
        self._frame = None

    def handle(self, op, *args):
        #DebugPrint(op, args)
        if self._client:
            if "mousepress" == op:
                x, y, act = args[0], args[1], args[2]
                self._client.control.touch(x, y, act)
            elif "mouserelease" == op:
                x, y, act = args[0], args[1], args[2]
                self._client.control.touch(x, y, act)
            elif "mousemove" == op:
                x, y, act = args[0], args[1], args[2]
                self._client.control.touch(x, y, act)
            elif "swip" == op:
                x, y, x1, y1 = args[0], args[1], args[2], args[3]
                self._client.control.swipe(x, y, x1, y1)
            elif "longpress" == op:
                x, y, msec = args[0], args[1], args[2]
                DebugPrint("long press!!!")
                self._client.control.longpress(x, y, delay=msec/1000.0)
            elif "touch" == op:
                x, y = args[0], args[1]
                self._client.control.touch(x, y, const.ACTION_DOWN)
                self._client.control.touch(x, y, const.ACTION_UP)
            elif "shell" == op:
                pass
        return super().handle(op, *args)
    
    def connect(self, serial):
        self._serial = serial

    def updateFrame(self):
        if self._client:
            self._client.frame()
        application.g_App.startTimer(0.01, self.updateFrame)

    def onStarted(self):
        application.g_App.startTimer(1, self.heartbeat)
        application.g_App.startTimer(0.01, self.updateFrame)

    def heartbeat(self):
        if self.isConnected():
            if not self._client:
                self.resetScrcpyClient()
        application.g_App.startTimer(1, self.heartbeat)

    def tryConnectDevice(self, reconnect: bool = False):
        if not self._serial:
            return
        #self._device = adb.device(serial=self._serial)
        if reconnect:
            rls = common.globaldefines.execute_command(f"adb reconnect")
            #DebugPrint(rls)
        else:
            rls = common.globaldefines.execute_command(f"adb connect {self._serial}")
            #DebugPrint(rls)

    def isConnected(self):
        if not self._serial:
            return False
        rls = common.globaldefines.execute_command("adb devices")
        output = rls["output"]
        #DebugPrint(rls)
        if f"{self._serial}\tdevice" in output:
            return True
        reconnect = False
        if f"{self._serial}\toffline" in output:
            reconnect = True
        self._client = None
        self.tryConnectDevice(reconnect=reconnect)
        return False

    def resetScrcpyClient(self):
        self._client = core.Client(
            device = self._serial
            , flip = False
            , bitrate = 1000000000
            , encoder_name = "OMX.google.h264.encoder"
            , max_fps= 20
        )
        self._client.add_listener(const.EVENT_INIT, self.onScrcpyInit)
        self._client.add_listener(const.EVENT_FRAME, self.onScrcpyFrame)
        self._client.startWithoutLoop()

    def onScrcpyInit(self):
        DebugPrint("scrcpy init")

    def onScrcpyFrame(self, frame):
        if frame is None:
            return
        self._frame = frame
        if self._makescreenshot:
            self._makescreenshot = False
            cv2.imwrite("screenshot.png", frame)

    def getFrame(self):
        return self._frame

    def getCurrentPackage(self):
        cmd = ["adb", "-s", self._serial, "shell", "dumpsys window | grep mCurrentFocus"]
        output = subprocess.check_output(cmd, universal_newlines=True, encoding="utf8")
        f = open("d:\\test.log", "w")
        f.write(output)
        f.close()
        pattern = re.escape("mCurrentFocus=Window{") + "(.*?)" + re.escape("}")
        match = re.search(pattern, output)
        if match:
            s = match.group(1)
            if s:
                l = s.split(" ")
                if len(l) == 3:
                    return l[2]
        return ""
    
    def checkAPPIsRunning(self, pkgname: str):
        pname = self.getCurrentPackage()
        if pname == pkgname:
            return True
        return False

    def startAPP(self, pkgname: str):
        cmd = ["adb", "-s", self._serial, "shell", "am", "start", "-n", pkgname]
        subprocess.check_output(cmd, universal_newlines=True, encoding="utf8")

    def stopAPP(self, pkgname: str):
        if "/" in pkgname:
            pkgname = pkgname.split("/")[0]
        cmd = ["adb", "-s", self._serial, "shell", "am", "force-stop", pkgname]
        subprocess.check_output(cmd, universal_newlines=True, encoding="utf8")
        
